package com.atguigu.juc.date928;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author: shenhao
 * @CreatTime: 2024/9/29 14:17
 * @Version: 1.0
 * 将关键字synchronized 和 lock锁进行比较,主要比较,lock锁可以退出,但sync必须等待堵塞直到获得锁
 * 在Java中，synchronized关键字和java.util.concurrent.locks.Lock接口提供的锁机制是两种不同的方式来实现线程同步。
 * 虽然它们都是用来控制对共享资源的访问，但它们是基于不同的实现机制，因此不能直接互相锁住。
 */
public class SyncVsLockDemo {
    public synchronized void m1(){
        System.out.println(Thread.currentThread().getName()+"--------- come in m1");
        //暂停几秒钟线程;
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    Lock lock = new ReentrantLock();
    public void m2(){
        if (lock.tryLock()) {
            try {
                System.out.println(Thread.currentThread().getName()+"--------- come in m2");
                //暂停几秒钟线程;
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }finally {
                lock.unlock();
            }
        }else {
            System.out.println(Thread.currentThread().getName()+"--------- lock used ,leave out");
        }
    }


    public void m3() throws InterruptedException {
        if (lock.tryLock(3l,TimeUnit.SECONDS)) {
            try {
                System.out.println(Thread.currentThread().getName()+"--------- come in m3");
                //暂停几秒钟线程;
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }finally {
                lock.unlock();
            }
        }else {
            System.out.println(Thread.currentThread().getName()+"--------- lock used ,leave out");
        }
    }
    // 证明lock为可重入锁, 方法内的锁,当线程已经获得了进入方法的锁,锁中之锁相当于一把锁
    public void m4() throws InterruptedException {
        lock.lock();
        try {
            System.out.println("11111111111");
            lock.lock();
            System.out.println("22222222222");
            lock.unlock();
//            lock.unlock();
        } finally {
            lock.unlock();
        }
    }


    public static void main(String[] args) {
        SyncVsLockDemo demo = new SyncVsLockDemo();
        Thread t1=new Thread(()->{
            try {
                demo.m1();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        },"t1");

        t1.start();

        //暂停毫秒
        try { TimeUnit.MILLISECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
        new Thread(()->{
            try {
                demo.m2();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        },"t2").start();
    }
}
